1. 正则表达式的应用

String 类提供的几个特殊方法

方法声明 功能描述
matches() 判断该字符串是否匹配指定的正则表达式
replaceAll() 将该字符串所有匹配正则表达式的子串替换成指定的字符串
replaceFirst() 将该字符串中第一个匹配正则表达式的子串替换成指定的字符串
split(String regex) 以regex为分隔符,将该字符串分割成多个子串

1.1 匹配功能

  1. public boolean matches(String regex) // 编译给定正则表达式并尝试将给定输入与其匹配。

校验邮箱

  1. package cn.itcast_02;
  2. import java.util.Scanner;
  3. /*
  4. * 校验邮箱
  5. *
  6. * 分析:
  7. * A:键盘录入邮箱
  8. * B:定义邮箱的规则
  9. * 1517806580@qq.com
  10. * liuyi@163.com
  11. * linqingxia@126.com
  12. * fengqingyang@sina.com.cn
  13. * fqy@itcast.cn
  14. * C:调用功能,判断即可
  15. * D:输出结果
  16. */
  17. public class RegexTest {
  18. public static void main(String[] args) {
  19. //键盘录入邮箱
  20. Scanner sc = new Scanner(System.in);
  21. System.out.println("请输入邮箱:");
  22. String email = sc.nextLine();
  23. //定义邮箱的规则
  24. //String regex = "[a-zA-Z_0-9]+@[a-zA-Z_0-9]{2,6}(\\.[a-zA-Z_0-9]{2,3})+";
  25. String regex = "\\w+@\\w{2,6}(\\.\\w{2,3})+";
  26. //调用功能,判断即可
  27. boolean flag = email.matches(regex);
  28. //输出结果
  29. System.out.println("flag:"+flag);
  30. }
  31. }

1.2 分割功能

  1. public String[] split(String regex) // 根据指定的正则表达式分割字符串

代码示例:我有如下一个字符串:”91 27 46 38 50”,请写代码实现最终输出结果是:”27 38 46 50 91”

  1. package cn.itcast_03;
  2. import java.util.Arrays;
  3. /*
  4. * 我有如下一个字符串:"91 27 46 38 50"
  5. * 请写代码实现最终输出结果是:"27 38 46 50 91"
  6. *
  7. * 分析:
  8. * A:定义一个字符串
  9. * B:把字符串进行分割,得到一个字符串数组
  10. * C:把字符串数组变换成int数组
  11. * D:对int数组排序
  12. * E:把排序后的int数组在组装成一个字符串
  13. * F:输出字符串
  14. */
  15. public class RegexTest {
  16. public static void main(String[] args) {
  17. // 定义一个字符串
  18. String s = "91 27 46 38 50";
  19. // 把字符串进行分割,得到一个字符串数组
  20. String[] strArray = s.split(" ");
  21. // 把字符串数组变换成int数组
  22. int[] arr = new int[strArray.length];
  23. for (int x = 0; x < arr.length; x++) {
  24. arr[x] = Integer.parseInt(strArray[x]);
  25. }
  26. // 对int数组排序
  27. Arrays.sort(arr);
  28. // 把排序后的int数组在组装成一个字符串
  29. StringBuilder sb = new StringBuilder();
  30. for (int x = 0; x < arr.length; x++) {
  31. sb.append(arr[x]).append(" ");
  32. }
  33. //转化为字符串
  34. String result = sb.toString().trim();
  35. //输出字符串
  36. System.out.println("result:"+result);
  37. }
  38. }

1.3 替换功能

  1. public String replaceAll(String regex,String replacement)

使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串。

  • 论坛中不能出现数字字符,用*替换
  1. package cn.itcast_04;
  2. /*
  3. * 替换功能
  4. * String类的public String replaceAll(String regex,String replacement)
  5. * 使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串。
  6. */
  7. public class RegexDemo {
  8. public static void main(String[] args) {
  9. // 定义一个字符串
  10. String s = "helloqq12345worldkh622112345678java";
  11. // 我要去除所有的数字,用*给替换掉
  12. // String regex = "\\d+";
  13. // String regex = "\\d";
  14. //String ss = "*";
  15. // 直接把数字干掉
  16. String regex = "\\d+";
  17. String ss = "";
  18. String result = s.replaceAll(regex, ss);
  19. System.out.println(result);
  20. }
  21. }

1.4 获取功能

Pattern和Matcher类的使用

  1. package cn.itcast_05;
  2. import java.util.regex.Matcher;
  3. import java.util.regex.Pattern;
  4. /*
  5. * 获取功能
  6. * Pattern和Matcher类的使用
  7. *
  8. * 模式和匹配器的基本使用顺序
  9. */
  10. public class RegexDemo {
  11. public static void main(String[] args) {
  12. // 模式和匹配器的典型调用顺序
  13. // 把正则表达式编译成模式对象
  14. Pattern p = Pattern.compile("a*b");
  15. // 通过模式对象得到匹配器对象,这个时候需要的是被匹配的字符串
  16. Matcher m = p.matcher("aaaaab");
  17. // 调用匹配器对象的功能
  18. boolean b = m.matches();
  19. System.out.println(b);
  20. //这个是判断功能,但是如果做判断,这样做就有点麻烦了,我们直接用字符串的方法做
  21. String s = "aaaaab";
  22. String regex = "a*b";
  23. boolean bb = s.matches(regex);
  24. System.out.println(bb);
  25. }
  26. }

1.5 Pattern 匹配模式

Pattern类为正则表达式的编译表示形式。指定为字符串的表达式必须首先被编译为此类的实例。然后,可将得到的模式用于创建Matcher对象,依照正则表达式,该对象可与任意字符序列匹配。执行匹配所涉及的所有状态都驻留在匹配器中,所以多个匹配器可以共享同一个模式。

方法声明 功能描述
compile() 把正则表达式编译成匹配模式
matcher() 根据匹配模式去匹配指定的字符串,得到匹配器

1.6 Matcher 匹配器

方法声明 功能描述
matches() 匹配字符串
find() 查找有没有满足条件的子串
group() 获取满足条件的子串
reset() 将Matcher的状态重新设置为最初的状态
reset(CharSequence input) 重新设置Matcher的状态,并且将候选字符序列设置为input后进行Matcher, 这个方法和重新创建一个Matcher一样,只是这样可以重用以前的对象。
start() 返回Matcher所匹配的字符串在整个字符串的的开始下标
start(int group) 指定你感兴趣的sub group,然后返回sup group(子分组)匹配的开始位置。
end() 返回在以前的匹配操作期间,由给定组所捕获子序列的最后字符之后的偏移量。
  • 注意事项

Pattern类为正则表达式的编译表示形式。指定为字符串的正则表达式必须首先被编译为此类的实例。然后,可将得到的模式用于创建Matcher对象,依照正则表达式,该对象可以与任意字符序列匹配。执行匹配所涉及的所有状态都驻留在匹配器中,所以多个匹配器可以共享同一模式

分组:简单的说,分组其实就是为了能够指定同一个规则可以使用多少次。正则表达式中的分组就是整个大的正则表达式和用()圈起来的内容。

在这个正则表达式”\w(\d\d)(\w+)”中

  • 分组0:是”\w(\d\d)(\w+)”
  • 分组1:是(\d\d)
  • 分组2:是(\w+)

如果我们稍稍变换一下,将原先的正则表达式改为”(\w)(\d\d)(\w+)”,我们的分组就变成了

  • 分组0:是”\w(\d\d)(\w+)”
  • 分组1:是”(\w)”
  • 分组2:是”(\d\d)”
  • 分组3:是”(\w+)”

我们看看和正则表达式”\w(\d\d)(\w+)”匹配的一个字符串A22happy

  • group(0)是匹配整个表达式的字符串的那部分A22happy
  • group(1)是第1组(\d\d)匹配的部分:22
  • group(2)是第2组(\w+)匹配的那部分happy
  1. public static void main(String[] args) {
  2. String Regex="\\w(\\d\\d)(\\w+)";
  3. String TestStr="A22happy";
  4. Pattern p=Pattern.compile(Regex);
  5. Matcher matcher=p.matcher(TestStr);
  6. if (matcher.find()) {
  7. int gc=matcher.groupCount();
  8. for (int i = 0; i <= gc; i++) {
  9. System.out.println("group "+i+" :"+matcher.group(i));
  10. }
  11. }
  12. }
  • start()方法的使用
  1. public static void testStart(){
  2. //创建一个 Matcher ,使用 Matcher.start()方法
  3. String candidateString = "My name is Bond. James Bond.";
  4. String matchHelper[] ={" ^"," ^"};
  5. Pattern p = Pattern.compile("Bond");
  6. Matcher matcher = p.matcher(candidateString);
  7. //找到第一个 'Bond'的开始下标
  8. matcher.find();
  9. int startIndex = matcher.start();
  10. System.out.println(candidateString);
  11. System.out.println(matchHelper[0] + startIndex);
  12. //找到第二个'Bond'的开始下标
  13. matcher.find();
  14. int nextIndex = matcher.start();
  15. System.out.println(candidateString);
  16. System.out.println(matchHelper[1] + nextIndex);
  17. }

运行结果:

正则表达式的应用 - 图1

  1. /**
  2. * 测试matcher.group方法
  3. */
  4. public static void testGroup() {
  5. // 创建一个 Pattern
  6. Pattern p = Pattern.compile("Bond");
  7. // 创建一个 Matcher ,以便使用 Matcher.group() 方法
  8. String candidateString = "My name is Bond. James Bond.";
  9. Matcher matcher = p.matcher(candidateString);
  10. // 提取 group
  11. matcher.find();
  12. System.out.println(String.format("group匹配的字符串 : %s",matcher.group()));
  13. System.out.println(String.format("匹配的开始位置 : %d", matcher.start()));
  14. System.out.println(String.format("匹配的结束位置 : %d", matcher.end()));
  15. System.out
  16. .println("---再次使用matcher.find()方法,看看matcher中group、start、end方法的效果");
  17. matcher.find();
  18. System.out.println(String.format("group匹配的字符串 : %s",matcher.group()));;
  19. System.out.println(String.format("匹配的开始位置 : %d", matcher.start()));
  20. System.out.println(String.format("匹配的结束位置 : %d", matcher.end()));
  21. System.out.println(String.format("candidateString字符串的长度 : %d", candidateString.length()));
  22. }

运行结果:

正则表达式的应用 - 图2

  • 获取由三个字符组成的单词
  1. package cn.itcast_05;
  2. import java.util.regex.Matcher;
  3. import java.util.regex.Pattern;
  4. /*
  5. * 获取功能:
  6. * 获取下面这个字符串中由三个字符组成的单词
  7. * da jia ting wo shuo,jin tian yao xia yu,bu shang wan zi xi,gao xing bu?
  8. */
  9. public class RegexDemo2 {
  10. public static void main(String[] args) {
  11. // 定义字符串
  12. String s = "da jia ting wo shuo,jin tian yao xia yu,bu shang wan zi xi,gao xing bu?";
  13. // 规则
  14. String regex = "\\b\\w{3}\\b";
  15. // 把规则编译成模式对象
  16. Pattern p = Pattern.compile(regex);
  17. // 通过模式对象得到匹配器对象
  18. Matcher m = p.matcher(s);
  19. // 调用匹配器对象的功能
  20. // 通过find方法就是查找有没有满足条件的子串
  21. // public boolean find()
  22. // boolean flag = m.find();
  23. // System.out.println(flag);
  24. // // 如何得到值呢?
  25. // // public String group()
  26. // String ss = m.group();
  27. // System.out.println(ss);
  28. //
  29. // // 再来一次
  30. // flag = m.find();
  31. // System.out.println(flag);
  32. // ss = m.group();
  33. // System.out.println(ss);
  34. while (m.find()) {
  35. System.out.println(m.group());
  36. }
  37. // 注意:一定要先find(),然后才能group()
  38. // IllegalStateException: No match found
  39. // String ss = m.group();
  40. // System.out.println(ss);
  41. }
  42. }
  • 判断身份证:要么是15位,要么是18位,最后一位可以为字母,并写程序提出其中的年月日。
  1. public static void main(String[] args) {
  2. testID_Card();
  3. }
  4. public static void testID_Card() {
  5. // 测试是否为合法的身份证号码
  6. String[] strs = { "130681198712092019", "13068119871209201x",
  7. "13068119871209201", "123456789012345", "12345678901234x",
  8. "1234567890123" };
  9. // 准备正则表达式(身份证有15位和18位两种,身份证的最后一位可能是字母)
  10. String regex = "(\\d{14}\\w)|\\d{17}\\w";
  11. // 准备开始匹配,判断所有的输入是否是正确的
  12. Pattern regular = Pattern.compile(regex); // 创建匹配的规则Patter
  13. StringBuilder sb = new StringBuilder();
  14. // 遍历所有要匹配的字符串
  15. for (int i = 0; i < strs.length; i++) {
  16. Matcher matcher = regular.matcher(strs[i]);// 创建一个Matcher
  17. sb.append("身份证: ");
  18. sb.append(strs[i]);
  19. sb.append(" 匹配:");
  20. sb.append(matcher.matches());
  21. System.out.println(sb.toString());
  22. sb.delete(0, sb.length());// 清空StringBuilder的方法
  23. }
  24. GetBirthDay(strs);
  25. }
  26. private static void GetBirthDay(String[] strs) {
  27. System.out.println("准备开始获取出生日期");
  28. // 准备验证规则
  29. Pattern BirthDayRegular = Pattern.compile("(\\d{6})(\\d{8})(.*)");
  30. // .*连在一起就意味着任意数量的不包含换行的字符
  31. Pattern YearMonthDayRegular = Pattern.compile("(\\d{4})(\\d{2})(\\d{2})");
  32. for (int i = 0; i < strs.length; i++) {
  33. Matcher matcher = BirthDayRegular.matcher(strs[i]);
  34. if (matcher.matches()) {
  35. Matcher matcher2 = YearMonthDayRegular.matcher(matcher.group(2));
  36. if (matcher2.matches()) {
  37. System.out.println(strs[i]+" 中的出生年月分解为: "+"年" + matcher2.group(1) + " 月:" + matcher2.group(2) + " 日:" + matcher2.group(3));
  38. }
  39. }
  40. }
  41. }

运行结果:

正则表达式的应用 - 图3

2. 正则表达式工具类

  1. import java.util.regex.Matcher;
  2. import java.util.regex.Pattern;
  3. /**
  4. * 正则工具类 提供验证邮箱、手机号、电话号码、身份证号码、数字等方法
  5. */
  6. public final class RegexUtils {
  7. /**
  8. * 验证Email
  9. *
  10. * @param email
  11. * email地址,格式:zhangsan@sina.com,zhangsan@xxx.com.cn,xxx代表邮件服务商
  12. * @return 验证成功返回true,验证失败返回false ^ :匹配输入的开始位置。 \:将下一个字符标记为特殊字符或字面值。
  13. * :匹配前一个字符零次或几次。 + :匹配前一个字符一次或多次。 (pattern) 与模式匹配并记住匹配。 x|y:匹配 x 或
  14. * y。 [a-z] :表示某个范围内的字符。与指定区间内的任何字符匹配。 \w :与任何单词字符匹配,包括下划线。
  15. *
  16. * {n,m} 最少匹配 n 次且最多匹配 m 次 $ :匹配输入的结尾。
  17. */
  18. public static boolean checkEmail(String email) {
  19. String regex = "^(\\w)+(\\.\\w+)*@(\\w)+((\\.\\w{2,3}){1,3})$";
  20. return Pattern.matches(regex, email);
  21. }
  22. /**
  23. * 验证身份证号码
  24. *
  25. * @param idCard
  26. * 居民身份证号码15位或18位,最后一位可能是数字或字母
  27. * @return 验证成功返回true,验证失败返回false
  28. */
  29. public static boolean checkIdCard(String idCard) {
  30. String regex = "[1-9]\\d{13,16}[a-zA-Z0-9]{1}";
  31. return Pattern.matches(regex, idCard);
  32. }
  33. /**
  34. * 验证手机号码(支持国际格式,+86135xxxx...(中国内地),+00852137xxxx...(中国香港))
  35. *
  36. * @param mobile
  37. * 移动、联通、电信运营商的号码段
  38. * <p>
  39. * 移动的号段:134(0-8)、135、136、137、138、139、147(预计用于TD上网卡)
  40. * 、150、151、152、157(TD专用)、158、159、187(未启用)、188(TD专用)
  41. * </p>
  42. * <p>
  43. * 联通的号段:130、131、132、155、156(世界风专用)、185(未启用)、186(3g)
  44. * </p>
  45. * <p>
  46. * 电信的号段:133、153、180(未启用)、189
  47. * </p>
  48. * <p>
  49. * 虚拟运营商的号段:170
  50. * </p>
  51. * @return 验证成功返回true,验证失败返回false
  52. */
  53. public static boolean checkMobile(String mobile) {
  54. String regex = "(\\+\\d+)?1[34578]\\d{9}$";
  55. return Pattern.matches(regex, mobile);
  56. }
  57. /**
  58. * 验证固定电话号码
  59. *
  60. * @param phone
  61. * 电话号码,格式:国家(地区)电话代码 + 区号(城市代码) + 电话号码,如:+8602085588447
  62. * <p>
  63. * <b>国家(地区) 代码 :</b>标识电话号码的国家(地区)的标准国家(地区)代码。它包含从 0 到 9
  64. * 的一位或多位数字, 数字之后是空格分隔的国家(地区)代码。
  65. * </p>
  66. * <p>
  67. * <b>区号(城市代码):</b>这可能包含一个或多个从 0 到 9 的数字,地区或城市代码放在圆括号——
  68. * 对不使用地区或城市代码的国家(地区),则省略该组件。
  69. * </p>
  70. * <p>
  71. * <b>电话号码:</b>这包含从 0 到 9 的一个或多个数字
  72. * </p>
  73. * @return 验证成功返回true,验证失败返回false
  74. */
  75. public static boolean checkPhone(String phone) {
  76. // String regex = "(\\+\\d+)?(\\d{3,4}\\-?)?\\d{7,8}$";
  77. String regex = "^1\\d{10}$";
  78. return Pattern.matches(regex, phone);
  79. }
  80. /**
  81. * 验证整数(正整数和负整数)
  82. *
  83. * @param digit
  84. * 一位或多位0-9之间的整数
  85. * @return 验证成功返回true,验证失败返回false
  86. */
  87. public static boolean checkDigit(String digit) {
  88. String regex = "\\-?[1-9]\\d+";
  89. return Pattern.matches(regex, digit);
  90. }
  91. /**
  92. * 验证整数和浮点数(正负整数和正负浮点数)
  93. *
  94. * @param decimals
  95. * 一位或多位0-9之间的浮点数,如:1.23,233.30
  96. * @return 验证成功返回true,验证失败返回false
  97. */
  98. public static boolean checkDecimals(String decimals) {
  99. String regex = "\\-?[1-9]\\d+(\\.\\d+)?";
  100. return Pattern.matches(regex, decimals);
  101. }
  102. /**
  103. * 验证空白字符
  104. *
  105. * @param blankSpace
  106. * 空白字符,包括:空格、\t、\n、\r、\f、\x0B
  107. * @return 验证成功返回true,验证失败返回false
  108. */
  109. public static boolean checkBlankSpace(String blankSpace) {
  110. String regex = "\\s+";
  111. return Pattern.matches(regex, blankSpace);
  112. }
  113. /**
  114. * 验证中文
  115. *
  116. * @param chinese
  117. * 中文字符
  118. * @return 验证成功返回true,验证失败返回false
  119. */
  120. public static boolean checkChinese(String chinese) {
  121. String regex = "^[\u4E00-\u9FA5]+$";
  122. return Pattern.matches(regex, chinese);
  123. }
  124. /**
  125. * 验证日期(年月日)
  126. *
  127. * @param birthday
  128. * 日期,格式:1992-09-03,或1992.09.03
  129. * @return 验证成功返回true,验证失败返回false
  130. */
  131. public static boolean checkBirthday(String birthday) {
  132. String regex = "[1-9]{4}([-./])\\d{1,2}\\1\\d{1,2}";
  133. return Pattern.matches(regex, birthday);
  134. }
  135. /**
  136. * 验证URL地址
  137. *
  138. * @param url
  139. * 格式:http://blog.csdn.net:80/xyang81/article/details/7705960? 或
  140. * http://www.csdn.net:80
  141. * @return 验证成功返回true,验证失败返回false
  142. */
  143. public static boolean checkURL(String url) {
  144. String regex = "(https?://(w{3}\\.)?)?\\w+\\.\\w+(\\.[a-zA-Z]+)*(:\\d{1,5})?(/\\w*)*(\\??(.+=.*)?(&.+=.*)?)?";
  145. return Pattern.matches(regex, url);
  146. }
  147. /**
  148. * 匹配中国邮政编码
  149. *
  150. * @param postcode
  151. * 邮政编码
  152. * @return 验证成功返回true,验证失败返回false
  153. */
  154. public static boolean checkPostcode(String postcode) {
  155. String regex = "[1-9]\\d{5}";
  156. return Pattern.matches(regex, postcode);
  157. }
  158. /**
  159. * 匹配IP地址(简单匹配,格式,如:192.168.1.1,127.0.0.1,没有匹配IP段的大小)
  160. *
  161. * @param ipAddress
  162. * IPv4标准地址
  163. * @return 验证成功返回true,验证失败返回false
  164. */
  165. public static boolean checkIpAddress(String ipAddress) {
  166. String regex = "[1-9](\\d{1,2})?\\.(0|([1-9](\\d{1,2})?))\\.(0|([1-9](\\d{1,2})?))\\.(0|([1-9](\\d{1,2})?))";
  167. return Pattern.matches(regex, ipAddress);
  168. }
  169. public static boolean checkNickname(String nickname) {
  170. String regex = "^[a-zA-Z0-9\u4E00-\u9FA5_]+$";
  171. return Pattern.matches(regex, nickname);
  172. }
  173. public static boolean hasCrossSciptRiskInAddress(String str) {
  174. String regx = "[`~!@#$%^&*+=|{}':;',\\[\\].<>~!@#¥%……&*——+|{}【】‘;:”“’。,、?-]";
  175. if (str != null) {
  176. str = str.trim();
  177. Pattern p = Pattern.compile(regx, Pattern.CASE_INSENSITIVE);
  178. Matcher m = p.matcher(str);
  179. return m.find();
  180. }
  181. return false;
  182. }
  183. }